package com.mcptt.config.body.info.mcdata.binary;

import com.cloudptt.api.pjsip.api.MessageInfo;
import com.cloudptt.api.product.log.Log;

import java.nio.charset.StandardCharsets;

public class FdSignalBody extends BinaryBody{
    protected static final byte TYPE_LEN = 1;
    protected static final byte DATE_LEN = 5;
    protected static final byte CONVERSATIONID_LEN = 16;
    protected static final byte MESSAGEID_LEN = 16;
    protected static final byte INREPOLY_LEN = 1;
    protected static final byte MATADE_DOWNLOAD_LEN = 1;
    protected static final byte PAYLOAD_LEN = 1;
    protected static final byte MATADE_LEN = 1;
    protected static final byte BODY_LEN = TYPE_LEN + DATE_LEN + CONVERSATIONID_LEN + MESSAGEID_LEN + INREPOLY_LEN + MATADE_DOWNLOAD_LEN;
    public FdSignalBody()
    {

    }
    public static String toBodyStr(MessageInfo info)
    {
        Log.debug(FdSignalBody.class,"toBodyStr info =  " + info);
        String fileUrl = info.getContent();
        byte[] fileUrlArray = fileUrl.getBytes(StandardCharsets.UTF_8);
        String metaData = info.getFileMetaData();
        byte[] metaDataArray = metaData.getBytes(StandardCharsets.UTF_8);
        int fileUrlLen = fileUrlArray.length;

        int dataLen =  metaDataArray.length;

        int allLen = BODY_LEN  + 1 + 2  + 1 + fileUrlLen + 1 + 2 + dataLen;
        byte[] allArray = new byte[allLen];
        allArray[0] = FD_SIGNALLING_PAYLOAD;//TYPE
        int index = 1;

        byte[] dateArr = longToByteArray(info.getDate());
        System.arraycopy(dateArr, 0, allArray, index, dateArr.length);//DATA AND TIME
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index +" data dateArr = ",dateArr);
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index +" allArray = ",allArray);

        index = index + dateArr.length;

        dateArr = info.getConversationIdByteArr();
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index + " dateArr.length = " + dateArr.length +" ConversationId dateArr = ",dateArr);
        System.arraycopy(dateArr, 0, allArray, index, 16);//ConversationId
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index,allArray);

        index = index + dateArr.length;

        dateArr = info.getMsgId().getBytes();
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index + " dateArr.length = " + dateArr.length + " MsgId dateArr = ",dateArr);
        System.arraycopy(dateArr, 0, allArray, index, dateArr.length);//MESSAGE ID
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index,allArray);

        index = index + dateArr.length;

        byte requestType = (byte)(IE_FD_DISPOSITION_REQ_TYPE + (info.getDispositionReqType()&0x0f));
        Log.debug(FdSignalBody.class,"toBodyStr requestType =  " + requestType + " index = " + index);
        allArray[index] = requestType;//INREPLOY
        Log.debug(FdSignalBody.class,"toBodyStr index = " + index ,allArray);

        index = index + 1;

        byte mandaryType = (byte)(IE_MANDARY_DOWNLOAD);// + (info.getDispositionReqType()&0xf0>>4));
        Log.debug(FdSignalBody.class,"toBodyStr mandaryType =  " + mandaryType + " index = " + index);
        allArray[index] = mandaryType;//MATA DOWNLOAD ID

        index = index + 1;

        Log.debug(FdSignalBody.class,"toBodyStr IE_PAYLOAD index = " + index);
        allArray[index] = IE_PAYLOAD;//PAYLOAD
        index = index + 1;

        byte[] lenArr = intToByteArray(fileUrlLen+1);
        Log.debug(FdSignalBody.class,"toBodyStr lenArr =  " ,lenArr);
        allArray[index] = lenArr[0];
        allArray[index + 1] = lenArr[1];//FILEURL LEN

        Log.debug(FdSignalBody.class,"toBodyStr fileUrlLen index = " + index);

        index = index + 2;

        allArray[index] = Type_FileURL;
        index = index + 1;
        System.arraycopy(fileUrlArray, 0, allArray, index, fileUrlLen);//FILEURL
        Log.debug(FdSignalBody.class,"toBodyStr allArray =  ",allArray);

        Log.debug(FdSignalBody.class,"toBodyStr fileUrl index = " + index);

        index = index + fileUrlLen;


        allArray[index] = IE_METADATA_COMPATIBLE;//METADATA TYPE
        index = index + 1;

        Log.debug(FdSignalBody.class,"toBodyStr 1 allArray =  ",allArray);

        byte[] dataLenArr = intToByteArray(dataLen);
        Log.debug(FdSignalBody.class,"toBodyStr dataLen =  " + dataLen + " dataLenArr =  " ,dataLenArr);
        allArray[index] = dataLenArr[0];
        allArray[index + 1] = dataLenArr[1];

        Log.debug(FdSignalBody.class,"toBodyStr 2 allArray =  ",allArray);
        Log.debug(FdSignalBody.class,"toBodyStr meata len index = " + index);

        index = index + 2;
        Log.debug(FdSignalBody.class,"toBodyStr dataLen =  "+ dataLen + " metaDataArray.length = " + metaDataArray.length + " allArray out = " + (allArray.length -index));
        System.arraycopy(metaDataArray, 0, allArray, index, dataLen);
        Log.debug(FdSignalBody.class,"toBodyStr allArray =  ",allArray);

        return byteArrayToHexStr(allArray);
    }


    protected static MessageInfo parseSignalPayload(byte signalType,byte[] contentArr)
    {
        MessageInfo info = new MessageInfo(signalType);
        Log.debug(FdSignalBody.class,"parseSignalPayload BODY_LEN =  " + BODY_LEN + " contentArr.length = " + contentArr.length);
        Log.debug(FdSignalBody.class,"parseSignalPayload contentArr =  " ,contentArr);
        // 检查索引和子组长度是否有效
//        if (BODY_LEN != contentArr.length) {
//            Log.debug(FdSignalBody.class,"parseSignalPayload Invalid start index or subgroup length, cannot extract subContentArr.");
//            return info;
//        }
        int startIndex = 1;//FD signalling payload message identity
        int len = 5;
        byte[] dataTimeArr = new byte[len];
        System.arraycopy(contentArr, startIndex, dataTimeArr, 0, len);
        Log.debug(FdSignalBody.class,"parseSignalPayload dataTimeArr =  " ,dataTimeArr);
        long dataSec = byteArrayToLong(dataTimeArr);
        Log.debug(FdSignalBody.class,"parseSignalPayload dataSec =  " + dataSec);
        info.setDate(dataSec);//Date and time

        startIndex = startIndex+5;
        len = 16;
        byte[] conversationIdArr = new byte[len];
        System.arraycopy(contentArr, startIndex, conversationIdArr, 0, len);
        Log.debug(FdSignalBody.class,"parseSignalPayload conversationIdArr =  " ,conversationIdArr);
        String conversationId = new String(conversationIdArr);
        Log.debug(FdSignalBody.class,"parseSignalPayload conversationId =  " + conversationId);
        info.setConversationId(conversationId);//Conversation ID

        startIndex = startIndex+16;
        len = 16;
        byte[] msgIdArr = new byte[len];
        System.arraycopy(contentArr, startIndex, msgIdArr, 0, len);
        Log.debug(FdSignalBody.class,"parseSignalPayload msgIdArr =  " ,msgIdArr);
        String msgId = new String(msgIdArr);
        Log.debug(FdSignalBody.class,"parseSignalPayload msgId =  " + msgId);
        info.setMsgId(msgId);//Message ID


        startIndex = startIndex+16;
        byte value1 = contentArr[startIndex];
        Log.debug(FdSignalBody.class,"parseSignalPayload value1 =  " + value1);

        byte bodyType = (byte) (value1 & 0xf0);
        Log.debug(FdSignalBody.class,"parseSignalPayload bodyType =  " + bodyType);//FD disposition request type

        value1 = (byte) (value1 & 0x0f);
        Log.debug(FdSignalBody.class,"parseSignalPayload value1 =  " + value1);//FD disposition request type

        /*Mandatory download begin*/
        byte value = contentArr[startIndex];
        Log.debug(FdSignalBody.class,"parseSignalPayload value =  " + value);
        bodyType = (byte) (value & 0xf0);
        Log.debug(FdSignalBody.class,"parseSignalPayload Mandatory download bodyType =  " + bodyType);//FD disposition request type
        if(bodyType == 1) {
            startIndex = startIndex + 1;
        }
        /*Mandatory download end*/

        byte value2 = contentArr[startIndex];
        bodyType = (byte) (value2 & 0xf0);
        Log.debug(FdSignalBody.class,"parseSignalPayload bodyType =  " + bodyType);

        value2 = (byte) ((value2 & 0x0f) << 4);
        Log.debug(FdSignalBody.class,"parseSignalPayload value2 =  " + value2);
        info.setDispositionReqType(value1+value2);
        startIndex = startIndex+1;

        bodyType = contentArr[startIndex];
        Log.debug(FdSignalBody.class,"parseSignalPayload bodyType =  " +bodyType);
        startIndex = startIndex+1;

        byte[] lenArr = new byte[2];
        lenArr[0] = contentArr[startIndex];
        lenArr[1] = contentArr[startIndex + 1];
        int fileUrlLen = byteArrToInt(lenArr);
        Log.debug(FdSignalBody.class,"parseSignalPayload fileUrlLen =  " +fileUrlLen);
        if (startIndex < 0 || startIndex >= contentArr.length ||
                startIndex + fileUrlLen > contentArr.length) {
            Log.debug(FdSignalBody.class,"parseSignalPayload fileUrlLen err.");
            return info;
        }

        startIndex = startIndex + 2;

        int type = contentArr[startIndex];
        Log.debug(FdSignalBody.class,"parseSignalPayload type =  " + type);
        info.setContentType(type);
        // 提取n位byte子组
        byte[] subContentArr = new byte[fileUrlLen-1];
        System.arraycopy(contentArr, startIndex+1, subContentArr, 0, fileUrlLen-1);
        Log.debug(FdSignalBody.class,"parseSignalPayload subContentArr =  " ,subContentArr);
        String content = new String(subContentArr, StandardCharsets.UTF_8);
        Log.debug(FdSignalBody.class,"parseSignalPayload content =  " + content);
        info.setContent(content);

        startIndex = startIndex + fileUrlLen;


        bodyType = contentArr[startIndex];//后续按type解
        Log.debug(FdSignalBody.class,"parseSignalPayload bodyType =  " +bodyType);
        startIndex = startIndex + 1;

        byte[] metaLenArr = new byte[2];
        metaLenArr[0] = contentArr[startIndex];
        metaLenArr[1] = contentArr[startIndex + 1];
        Log.debug(FdSignalBody.class,"parseSignalPayload metaLenArr =  ",metaLenArr);

        int metaLen = byteArrToInt(metaLenArr);
        Log.debug(FdSignalBody.class,"parseSignalPayload metaLen =  " +metaLen);
        Log.debug(FdSignalBody.class,"parseSignalPayload startIndex =  " +startIndex + " contentArr.length = " + contentArr.length + " startIndex + metaLen = " + (startIndex + metaLen));
        if (startIndex < 0 || startIndex >= contentArr.length ||
                startIndex + metaLen > contentArr.length) {
            Log.debug(FdSignalBody.class,"parseSdsPayload metaLen err.");
            return info;
        }

        startIndex = startIndex + 2;


        byte[] metaArr = new byte[metaLen];
        System.arraycopy(contentArr, startIndex, metaArr, 0, metaLen);
        Log.debug(FdSignalBody.class,"parseSignalPayload metaArr =  " ,metaArr);
        String metaStr = new String(metaArr, StandardCharsets.UTF_8);
        Log.debug(FdSignalBody.class,"parseSignalPayload metaStr =  " + metaStr);
        info.setFileMetaData(metaStr);

        return info;
    }
}
